package com.yxhl.zoume.account.activity;

import android.app.LoaderManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.annotation.NonNull;
import android.support.design.widget.TextInputEditText;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxTextView;
import com.yxhl.zoume.R;
import com.yxhl.zoume.account.event.LoginStatus;
import com.yxhl.zoume.account.event.LoginViewBackEvent;
import com.yxhl.zoume.account.event.UserAbortLoginEvent;
import com.yxhl.zoume.account.event.UserLoginEvent;
import com.yxhl.zoume.account.presenter.MobileLoginPresenter;
import com.yxhl.zoume.account.presenter.ReadSmsPresenter;
import com.yxhl.zoume.account.view.MobileLoginView;
import com.yxhl.zoume.account.view.ReadSmsView;
import com.yxhl.zoume.common.ui.activity.base.BaseActivityWithToolBar;
import com.yxhl.zoume.core.func.webpage.info.WebPageEntrance;
import com.yxhl.zoume.data.http.model.account.ZMAccount;
import com.yxhl.zoume.data.http.rest.response.login.MobileLoginResponse;
import com.yxhl.zoume.data.rxbus.RxBus;
import com.yxhl.zoume.di.component.account.AccountComponent;
import com.yxhl.zoume.di.component.account.DaggerAccountComponent;
import com.yxhl.zoume.di.module.ActivityModule;
import com.yxhl.zoume.di.module.account.AccountModule;
import com.yxhl.zoume.domain.interactor.ZMSubscriber;
import com.yxhl.zoume.utils.AccountUtils;
import com.yxhl.zoume.utils.DiskCacheUtils;
import com.yxhl.zoume.utils.NetworkUtils;
import com.yxhl.zoume.utils.PromptUtils;
import com.yxhl.zoume.utils.RegexUtils;
import com.yxhl.zoume.utils.permission.PermissionHelper;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.OnClick;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.functions.Func2;

/**
 * 手机号码登录
 * Created by Xboy on 16/2/24.
 */
public class MobileLoginActivity extends BaseActivityWithToolBar implements MobileLoginView, ReadSmsView {
    private final static long COUNTDOWN_INTERVAL = 60;
    private final static long SMS_CODE_LENGTH = 4;

    // 手机号
    @BindView(R.id.mobile_et)
    public TextInputEditText mMobileEditText;
    // 短信验证码
    @BindView(R.id.sms_code_et)
    public TextInputEditText mSmsCodeEditText;
    // 获取验证码
    @BindView(R.id.get_smscode_button)
    public Button mSmsButton;
    // 登录按钮
    @BindView(R.id.mobile_login_button)
    public Button mMobileLoginButton;
    // 注册协议
    @BindView(R.id.agreement_tv)
    public TextView mAgreementTextView;
    //清除
    @BindView(R.id.iv_sms_clean)
    ImageView smsClean;
    // Presenter
    @Inject
    MobileLoginPresenter mobileLoginPresenter;
    @Inject
    ReadSmsPresenter mReadSmsPresenter;
    // 倒计时计时器
    private CountDownTimer countDownTimer;
    // Component
    private AccountComponent accountComponent;

    private LoginStatus isLogin = LoginStatus.NOT_LOGIN;


    /**
     * 打开登录页面
     *
     * @param context
     * @return
     */
    public static Intent getCallingIntent(Context context) {
        Intent intent = new Intent(context, MobileLoginActivity.class);
        return intent;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setToolbarTitle(getString(R.string.login_title));

        // 绑定View
        mobileLoginPresenter.attachView(this);
        mReadSmsPresenter.attachView(this);
        mReadSmsPresenter.setSmsCodeEt(mSmsCodeEditText);

        mobileLoginLogicControl();
    }

    /**
     * RxJava Verson: Login Logic Control
     */
    private void mobileLoginLogicControl() {
        // MobileNumber
        Observable<Boolean> mobileNumberObservable = RxTextView.textChanges(mMobileEditText)
                .map(new Func1<CharSequence, Boolean>() {
                    @Override
                    public Boolean call(CharSequence charSequence) {
                        return RegexUtils.isValidMobile(charSequence.toString());
                    }
                })
                .skip(1);

        // SmsCode
        Observable<Boolean> smsObservable = RxTextView.textChanges(mSmsCodeEditText)
                .map(new Func1<CharSequence, Boolean>() {
                    @Override
                    public Boolean call(CharSequence charSequence) {
                        return charSequence.toString().length() == SMS_CODE_LENGTH;
                    }
                })
                .skip(1);

        // Both
        Observable<Boolean> bothObservable = Observable.combineLatest(mobileNumberObservable, smsObservable, new Func2<Boolean, Boolean, Boolean>() {
            @Override
            public Boolean call(Boolean isMobileNumberValid, Boolean isSmsCodeValid) {
                return isMobileNumberValid && isSmsCodeValid;
            }
        });

        // SmsCodeButton
        mobileNumberObservable.subscribe(new ZMSubscriber<Boolean>() {
            @Override
            public void onNext(Boolean isEnabled) {
                setupSmsButton("获取验证码", isEnabled);
            }
        });
        // Request SmsCode
        RxView.clicks(mSmsButton)
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        requestSmsCode();
                    }
                });

        // LoginButton
        bothObservable.subscribe(new ZMSubscriber<Boolean>() {
            @Override
            public void onNext(Boolean isEnabled) {
                mMobileLoginButton.setEnabled(isEnabled);
            }
        });

        RxView.clicks(smsClean)
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        mSmsCodeEditText.setText("");
                    }
                });

        // Login
        RxView.clicks(mMobileLoginButton)
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        loginByMobile();
                    }
                });
    }

    @Override
    protected void onResume() {
        super.onResume();
        mobileLoginPresenter.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mobileLoginPresenter.onPause();
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.activity_mobile_login;
    }


    @Override
    protected void onHeaderLeftClick(View view) {
        onBackPressed();
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        // 用户从登录界面直接返回, 发送事件用于处理界面跳转
        RxBus.getInstance().send(new UserAbortLoginEvent());
        RxBus.getInstance().send(new LoginViewBackEvent(isLogin));
    }

    @Override
    protected void onHeaderRightClick(View view) {
    }

    @Override
    protected void initializeInjector() {
        // 依赖注入

        accountComponent = DaggerAccountComponent.builder()
                .activityModule(new ActivityModule(this))
                .appComponent(getAppComponent())
                .accountModule(new AccountModule())
                .build();
        accountComponent.inject(this);
    }

    /**
     * 获取短信验证码
     */
    private void requestSmsCode() {
        if (NetworkUtils.getInstance(this).isConnected()) {
            // Start CountdownTimer
            enableSmsButton(false);
            startCountDownTimer(COUNTDOWN_INTERVAL);

            // Active Sms Edit
            mSmsCodeEditText.requestFocus();

            // Request内容观察者
            mReadSmsPresenter.registerContentObserver();
            mobileLoginPresenter.fetchSmsCode(mobileNumber());
        } else {
            PromptUtils.showShort(this, "网络不可用");
        }
    }

    /**
     * 用户登录请求
     */
    public void loginByMobile() {
        if (NetworkUtils.getInstance(this).isConnected()) {
            String deviceToken = DiskCacheUtils.getInstance(accountComponent.context()).getDeviceToken();
            mobileLoginPresenter.loginByMobile(mobileNumber(), smsCode(), deviceToken);
        } else {
            PromptUtils.showShort(this, "网络不可用");
        }
    }

    /**
     * 查看注册协议
     */
    @OnClick(R.id.agreement_tv)
    public void openRegisterAgreement() {
        getAppComponent().navigator().navigateToWebPageActivity(this, WebPageEntrance.REGISTER_AGREEMENT);
    }

    @Override
    public void showSmsCodeSendToast() {
        PromptUtils.showShort(this, R.string.sms_code_send);
    }

    @Override
    public void showSmsCodeErrorMessage(String errorCode, String errorMessage) {
        PromptUtils.showShort(this, errorMessage);
        stopCountDownTimer();
        switch (errorCode) {
            case "FREQUENCY_SMS":
                setupSmsButton("重新获取", true);
                break;
        }
    }

    @Override
    public void showLoadingIndicator() {
    }

    @Override
    public void hideLoadingIndicator() {
    }

    @Override
    public void showErrorMessage(String errorCode, String errorMessage) {
        PromptUtils.showShort(this, errorMessage);
    }


    /**
     * 登录请求结果
     *
     * @param mobileLoginResponse
     */
    @Override
    public void renderMobileLoginResult(MobileLoginResponse mobileLoginResponse) {

        isLogin = LoginStatus.LOGIN;
        // 保存账号信息
        ZMAccount account = new ZMAccount(mobileNumber(), mobileLoginResponse.getAccessToken());
        AccountUtils.getInstance(this).saveAccount(account);

        // Stop CountdownTimer
        stopCountDownTimer();

        // 发送登录事件
        RxBus.getInstance().send(new UserLoginEvent());

        // 关闭登录页面
        finish();
    }

    /**
     * 手机号码
     *
     * @return
     */
    private String mobileNumber() {
        if (mMobileEditText != null) {
            return mMobileEditText.getText().toString();
        }
        return "";
    }

    /**
     * 短信验证码
     *
     * @return
     */
    private String smsCode() {
        return mSmsCodeEditText.getText().toString();
    }

    private void setupSmsButton(String text, Boolean enabled) {
        mSmsButton.setText(text);
        enableSmsButton(enabled);
    }

    private void enableSmsButton(boolean enabled) {
        if (!enabled) {
            if (countDownTimer != null) {
                countDownTimer.cancel();
            }
        }
        mSmsButton.setEnabled(enabled);
    }

    /**
     * 倒计时方法
     * 计时步长:1s
     */
    private void startCountDownTimer(final long time) {
        countDownTimer = new CountDownTimer(time * 1000, 1000) {

            public void onTick(long millisUntilFinished) {
                if (mSmsButton != null) {
                    mSmsButton.setText(millisUntilFinished / 1000 + "秒");
                }
            }

            public void onFinish() {
                setupSmsButton("重新获取", true);
            }
        };
        countDownTimer.start();
    }

    private void stopCountDownTimer() {
        if (null != countDownTimer) {
            countDownTimer.cancel();
            mSmsButton.setText("获取验证码");
        }
    }

    @Override
    public void initReadSmsLoader() {
        LoaderManager loaderManager = getLoaderManager();
        if (loaderManager != null) {
            loaderManager.initLoader(0, null, mReadSmsPresenter.new ReadSmsLoaderListener());
        }
    }

    @Override
    public void takeReadSmsPermission() {
        PermissionHelper.takeReadSmsPermission(this, PermissionHelper.REQUEST_CODE_READ_SMS);
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case PermissionHelper.REQUEST_CODE_READ_SMS:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    initReadSmsLoader();
                }
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (countDownTimer != null) {
            countDownTimer.cancel();
        }
        mobileLoginPresenter.onDestroy();
        mReadSmsPresenter.onDestroy();
    }
}
